package com.atguigu.dao;

import com.atguigu.utils.JdbcUtils;

import java.lang.reflect.Field;
import java.sql.*;
import java.util.ArrayList;

public abstract class BaseDao {
    /*
     * 通用的增、删、改的方法
     */
    protected int update(String sql, Object... args) throws SQLException {
        Connection connection = JdbcUtils.getConnection();
        PreparedStatement ps = connection.prepareStatement(sql);

        if (args != null && args.length > 0) {
            for (int i = 0; i < args.length; i++) {
                ps.setObject(i + 1, args[i]);
            }
        }

        int len = ps.executeUpdate();
        ps.close();

        if (connection.getAutoCommit()) {
            JdbcUtils.closeConnection();
        }
        return len;
    }

    /*
     * 通用的查询多个Javabean对象的方法
     */
    protected <T> ArrayList<T> query(Class<T> clazz, String sql, Object... args) throws Exception {
        Connection connection = JdbcUtils.getConnection();
        PreparedStatement ps = connection.prepareStatement(sql);

        if (args != null && args.length > 0) {
            for (int i = 0; i < args.length; i++) {
                ps.setObject(i + 1, args[i]);
            }
        }

        ArrayList<T> list = new ArrayList<>();
        ResultSet res = ps.executeQuery();

        ResultSetMetaData metaData = res.getMetaData();
        int columnCount = metaData.getColumnCount();

        while (res.next()) {
            T t = clazz.getDeclaredConstructor().newInstance();

            for (int i = 1; i <= columnCount; i++) {
                Object value = res.getObject(i);
                String columnLabel = metaData.getColumnLabel(i); // 优先取别名

                Field field = null;
                try {
                    // 先尝试原始名
                    field = clazz.getDeclaredField(columnLabel);
                } catch (NoSuchFieldException e1) {
                    try {
                        // 再尝试小写
                        field = clazz.getDeclaredField(columnLabel.toLowerCase());
                    } catch (NoSuchFieldException e2) {
                        try {
                            // 再尝试大写
                            field = clazz.getDeclaredField(columnLabel.toUpperCase());
                        } catch (NoSuchFieldException e3) {
                            // 彻底找不到就跳过该字段
                            continue;
                        }
                    }
                }

                field.setAccessible(true);
                field.set(t, value);
            }

            list.add(t);
        }

        res.close();
        ps.close();
        if (connection.getAutoCommit()) {
            JdbcUtils.closeConnection();
        }
        return list;
    }

    /*
     * 查询单个对象
     */
    protected <T> T queryBean(Class<T> clazz, String sql, Object... args) throws Exception {
        ArrayList<T> list = query(clazz, sql, args);
        if (list == null || list.isEmpty()) {
             return null;
        }
        return list.get(0);
    }
}
